﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Comdiv.QWeb.Factory;
using NUnit.Framework;

namespace Comdiv.QWeb.Test.HttpHandling
{

	[TestFixture]
	public class base_qweb_runner_test
	{
		public class test_type_lib:ITypeLocator {
			public class sample_action1:ActionBase {
				protected override object process() {
					return Context.Parameters;
				}
			}
			public Type Get<BASETYPE>(string name, bool throwexception) {
				if (name == "sample.action1") return typeof (sample_action1);
				return null;
			}

			public Type[] GetAll<BASETYPE>(bool throwexception) {
			    return Type.EmptyTypes;
			}
		}

		public QWebServiceRegistry getRegistry() {
			var result = new QWebServiceRegistry();
			result.RegisterService<ITypeLocator,test_type_lib>();
			return result;
		}

		void simple_test(string type, string expected) {
			if(!string.IsNullOrWhiteSpace(type)) {
				type = "." + type;
			}
			type = type ?? "";
			var context = new QWebContext("http://local/sample/action1"+type+".qweb").Set("x", 1).Set("y", 2);
			var sw = new StringWriter();
			context.Output = sw;
			QWebContext.Current = context;
			new QWebHandler(getRegistry()).ProcessRequest(context);
			Assert.AreEqual(expected, sw.ToString());
		}

		void simple_echo_test(string type, string expected)
		{
			if (!string.IsNullOrWhiteSpace(type))
			{
				type = "." + type;
			}
			type = type ?? "";
			var context = new QWebContext("http://local/qweb/echo" + type + ".qweb").Set("x", 1).Set("y", 2);
			var sw = new StringWriter();
			context.Output = sw;
			new QWebHandler(getRegistry()).ProcessRequest(context);
			Assert.AreEqual(expected, sw.ToString());
		}

		[Test]
		public void can_load_action_from_type_library_and_execute_it_js() {
			simple_test("", "{x: '1', y: '2', }");
		}

		[Test]
		public void can_load_action_from_type_library_and_execute_it_xml()
		{
			simple_test("xml", "<root><item key=\"x\">1</item><item key=\"y\">2</item></root>");


		}
		[Test]
		public void can_load_action_from_type_library_and_execute_it_json()
		{
			simple_test("json", @"{""x"": ""1"", ""y"": ""2""}");
		}

		[Test]
		public void can_load_action_from_type_library_and_execute_it_md5()
		{
			simple_test("md5", @"NkMzdMR92QGm37aKZTZ6KA==");
		}


		[Test]
		public void can_load_echo_action_from_type_library_and_execute_it_js()
		{
			simple_echo_test("", "{x: '1', y: '2', }");
		}

		[Test]
		public void can_load_echo_action_from_type_library_and_execute_it_xml()
		{
			simple_echo_test("xml", "<root><item key=\"x\">1</item><item key=\"y\">2</item></root>");


		}
		[Test]
		public void can_load_echo_action_from_type_library_and_execute_it_json()
		{
			simple_echo_test("json", @"{""x"": ""1"", ""y"": ""2""}");
		}

		[Test]
		public void can_load_echo_action_from_type_library_and_execute_it_md5()
		{
			simple_echo_test("md5", @"NkMzdMR92QGm37aKZTZ6KA==");
		}


		[Render("ignoreresult")]
		public class ignoreresult_render:IRender {
			public bool NeedResult {
				get { return false; }
			}

			public void Render(QWebContext context) {
				
			}

			public void RenderError(Exception error, QWebContext context) {
				throw new NotImplementedException();
			}
		}

		[Action("sample.withresult")]
		public class withresultAction:IAction {
			public static int created;
			public static int processed;
			public withresultAction() {
				created += 1;
			}
			public object Process(QWebContext context) {
				processed += 1;
				return true;
			}
		}

		[Test]
		public void if_render_not_need_result_action_not_instanced_and_runned() {
			withresultAction.created = 0;
			withresultAction.processed = 0;
			var ctx = new QWebHandler().ProcessRequest(new QWebContext("http://localhost/sample/withresult.ignoreresult.qweb"));
			Assert.Null(ctx.ActionResult);
			Assert.AreEqual(0,withresultAction.created);
			Assert.AreEqual(0, withresultAction.processed);
		}
		[Test]
		public void if_render_need_result_action_not_instanced_and_runned()
		{
			withresultAction.created = 0;
			withresultAction.processed = 0;
			var ctx = new QWebHandler().ProcessRequest(new QWebContext("http://localhost/sample/withresult.js.qweb"));
			Assert.AreEqual(true,ctx.ActionResult);
			Assert.AreEqual(1, withresultAction.created);
			Assert.AreEqual(1, withresultAction.processed);
		}
	}

}
